package net.xiangcaowuyu.quartztask.controller;

import net.xiangcaowuyu.quartztask.common.constant.ApiException;
import net.xiangcaowuyu.quartztask.common.constant.ApiResultEnum;
import net.xiangcaowuyu.quartztask.common.constant.Result;
import net.xiangcaowuyu.quartztask.entity.TaskQuartz;
import net.xiangcaowuyu.quartztask.service.TaskQuartzService;
import org.quartz.*;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author laughing
 * @date 2020/9/30
 * @site https://www.lisen.org
 */
@RestController
public class QuartzController {

    @Resource
    Scheduler scheduler;

    @Resource
    TaskQuartzService taskQuartzService;

    /**
     * 新增或者保存任务
     * 任务只是存储到task_quartz表中，任务启动时，插入quartz表
     *
     * @param taskQuartz 实体
     * @return 结果
     */
    @RequestMapping("saveQuartz")
    public Result save(@RequestBody TaskQuartz taskQuartz) {
        TaskQuartz task = taskQuartzService.selectByJobNameAndJobGroup(taskQuartz.getJobName(), taskQuartz.getJobGroup());
        if (task == null) {
            task = new TaskQuartz();
            BeanUtils.copyProperties(taskQuartz, task);
            taskQuartzService.insertSelective(task);
        } else {
            taskQuartzService.updateByPrimaryKeySelective(taskQuartz);
        }
        return Result.ok();
    }

    /**
     * 启用任务
     * 启动任务时，将任务信息持久化到quartz表中
     *
     * @param taskQuartz 实体
     * @return 结果
     */
    @RequestMapping("startJob")
    public Result startJob(@RequestBody TaskQuartz taskQuartz) {
        try {
            JobKey jobKey = getJobKeyByTaskQuartz(taskQuartz);
//            存在先删除
            if (scheduler.checkExists(jobKey)) {
                scheduler.deleteJob(jobKey);
            }
            Class classz = Class.forName(taskQuartz.getJobClassName());
            JobDetail jobDetail = JobBuilder.newJob()
                    .withDescription(taskQuartz.getDescription())
                    .withIdentity(jobKey)
                    .usingJobData("blog", "https://www.xiangcaowuyu.net")
                    .ofType(classz).build();
            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity("Trigger_" + taskQuartz.getJobName(), "TriggerGroup_" + taskQuartz.getJobGroup())
                    .withSchedule(CronScheduleBuilder.cronSchedule(taskQuartz.getCronExpression()))
                    .startNow()
                    .build();
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (Exception exception) {
            return Result.error(exception.getMessage());
        }
        return Result.ok();
    }

    /**
     * 暂停任务
     *
     * @param taskQuartz 实体
     * @return 结果
     */
    @RequestMapping("shutdown")
    public Result shutdown(@RequestBody TaskQuartz taskQuartz) {
        try {
            JobKey jobKey = getJobKeyByTaskQuartz(taskQuartz);
            scheduler.pauseJob(jobKey);
            return Result.ok();
        } catch (Exception ex) {
            return Result.error(ex.getMessage());
        }
    }

    /**
     * 恢复任务
     *
     * @param taskQuartz 实体
     * @return 结果
     */
    @RequestMapping("resumeJob")
    public Result resumeJob(@RequestBody TaskQuartz taskQuartz) {
        try {
            JobKey jobKey = getJobKeyByTaskQuartz(taskQuartz);
            scheduler.resumeJob(jobKey);
            return Result.ok();
        } catch (Exception ex) {
            return Result.error(ex.getMessage());
        }
    }

    /**
     * 删除任务
     *
     * @param taskQuartz 实体
     * @return 结果
     */
    @RequestMapping("removeJob")
    public Result removeJob(@RequestBody TaskQuartz taskQuartz) {
        try {
            JobKey jobKey = getJobKeyByTaskQuartz(taskQuartz);
            scheduler.deleteJob(jobKey);
            taskQuartzService.deleteByJobNameAndJobGroup(taskQuartz.getJobName(),taskQuartz.getJobGroup());
            return Result.ok();
        } catch (Exception ex) {
            return Result.error(ex.getMessage());
        }
    }

    /**
     * @param taskQuartz
     * @return
     */
    private JobKey getJobKeyByTaskQuartz(TaskQuartz taskQuartz) {
        TaskQuartz task = taskQuartzService.selectByJobNameAndJobGroup(taskQuartz.getJobName(), taskQuartz.getJobGroup());
        if (task == null) {
            throw new ApiException(ApiResultEnum.PARAMETER_NULL, "根据名称及分组，未获取到任务信息");
        }
        String jobName = task.getJobName();
        String jobGroup = task.getJobGroup();
        JobKey jobKey = new JobKey(jobName, jobGroup);
        return jobKey;
    }

}
